package com.dhh.sky.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.webkit.MimeTypeMap;
import com.dhh.sky.R;
import com.dhh.sky.SDAApplication;
import com.dhh.sky.activity.AudioPlayerActivity;
import com.dhh.sky.activity.BasicActivity;
import com.dhh.sky.activity.EditorActivity;
import com.dhh.sky.activity.FileListActivity;
import com.dhh.sky.activity.ImagePagerActivity;
import com.dhh.sky.dao.DataBaseHelper;
import com.dhh.sky.dao.FileDAO;
import com.dhh.sky.model.SkyDriveAlbum;
import com.dhh.sky.model.SkyDriveFolder;
import com.dhh.sky.model.SkyDriveObject;
import com.dhh.sky.model.SkyDrivePhoto;
import com.dhh.sky.service.OpenOperationService;
import com.microsoft.live.LiveAuthClient;
import com.microsoft.live.LiveAuthException;
import com.microsoft.live.LiveAuthListener;
import com.microsoft.live.LiveConnectClient;
import com.microsoft.live.LiveConnectSession;
import com.microsoft.live.LiveOperation;
import com.microsoft.live.LiveStatus;

public class FileManager {
	public static final String director = Environment.getExternalStorageDirectory().getPath();
	private FileDAO dao;
	private Context context;
	
	public FileManager(DataBaseHelper db){
		dao = new FileDAO(db); 
	}
	
	public FileManager(Context context){
		this.context = context;
		dao = new FileDAO(new DataBaseHelper(context)); 
	}
	
	public List<SkyDriveObject> getFiles(String parent){
		return dao.getSkyObjectsByParent(parent);
	}
	
	public SkyDriveObject getFile(String path){
		return dao.getSkyObjects(path);
	}
	
	public SkyDriveObject getFileByName(String name){
		return dao.getSkyObjectByName(name);
	}
	
	public SkyDriveObject getFileByName(String name,String parent){
		return dao.getSkyObjectByName(name,parent);
	}
	
	public List<SkyDrivePhoto> getPhotos(String parent){
		List<SkyDrivePhoto> photos = new ArrayList<SkyDrivePhoto>();
		List<SkyDriveObject> files = this.getFiles(parent);
		for(SkyDriveObject file : files){
			if(file.getType().equals(SkyDrivePhoto.TYPE)){
				SkyDrivePhoto photo = (SkyDrivePhoto) file;
				photos.add(photo);
			}
		}
		return photos;
	}
	
	public boolean needSync(String folderId){
		boolean flag = false;
		try{
			SkyDriveObject obj = dao.getSkyLastObjects(folderId);			
			if(obj!=null){
				long start = Long.valueOf(obj.getMeta());
				long end = new Date().getTime();
				if((end-start)>(4*3600*1000)){
					flag = true;
				}
			}else{
				flag = true;
			}
		}catch(Exception e){
			flag = true;
		}
		return flag;
	}
	
	public int getFolderChildrenCount(String folderId){
		int count = 0;
		try{
			SkyDriveObject obj = dao.getSkyObjects(folderId);
			if(obj==null){
				count = 1;
			}else if(SkyDriveFolder.TYPE.equals(obj.getType())){
				SkyDriveFolder folder = (SkyDriveFolder) obj;
				count = folder.getCount();
			}else if(SkyDriveAlbum.TYPE.equals(obj.getType())){
				SkyDriveAlbum album = (SkyDriveAlbum) obj;
				count = album.getCount();
			}
		}catch(Exception e){
			Log.e(Constant.TAG, e.getMessage());
		}
		
		return count;
	}
	
	public boolean update(List<SkyDriveObject> os,String parent){
		boolean flag = true;
		try{
			dao.delFileByParent(parent);		
			for(SkyDriveObject o : os){
				if("me/skydrive".equalsIgnoreCase(parent)){
					o.setParent(parent);
					o.getParentId();
				}
			}
			
			dao.addFiles(os);
			
		}catch(Exception e){
			e.printStackTrace();
			flag = false;
		}
		
		return flag;
	}
	
	public boolean updateRecentDocs(List<SkyDriveObject> os,String parent){
		boolean flag = true;
		try{
			dao.delFileByParent(Constant.SKYFRIVE_PATH_RECENT_DOCS);		
			for(SkyDriveObject o : os){
				o.setParent(Constant.SKYFRIVE_PATH_RECENT_DOCS);
			}
			
			dao.addFiles(os);
			
		}catch(Exception e){
			e.printStackTrace();
			flag = false;
		}
		
		return flag;
	}
	
	public boolean updateSharedDocs(List<SkyDriveObject> os,String parent){
		boolean flag = true;
		try{
			dao.delFileByParent(Constant.SKYFRIVE_PATH_SHARED);		
			for(SkyDriveObject o : os){
				o.setParent(Constant.SKYFRIVE_PATH_SHARED);
			}
			
			dao.addFiles(os);
			
		}catch(Exception e){
			e.printStackTrace();
			flag = false;
		}
		
		return flag;
	}
	
	public boolean doCopy(String path,String uParent){
		try{
			SkyDriveObject file = dao.getSkyObjects(path);
			file.setParent(uParent);
			dao.addFile(file);	
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}	
		return true;
	}
	
	public boolean updateName(String path,String name){
		return dao.updateName(path, name);
	}
	
	public boolean delFile(String path){
		return dao.delFile(path);
	}
	
	public boolean addFile(SkyDriveObject file){
		return dao.addFile(file);
	}
	
	public void doSync(final BasicActivity context,final String path){
		try {			
			final SDAApplication app = ((SDAApplication) context.getApplication());
			final FileListActivity activity = (FileListActivity) context;
			LiveConnectClient mClient = app.getConnectClient();
			if(mClient!=null){
				syncFiles(mClient,path);
			}else{
				final LiveAuthClient aClient = new LiveAuthClient(context,Config.CLIENT_ID);
				context.onProgressStatus(true);
				aClient.initialize(Arrays.asList(Config.SCOPES), new LiveAuthListener(){
		            @Override
		            public void onAuthError(LiveAuthException exception, Object userState) {
		            	context.sendToast(context.getString(R.string.msg_error_network));
		                context.onProgressStatus(false);
		            }

		            @Override
		            public void onAuthComplete(LiveStatus status,LiveConnectSession session,Object userState) {
		                if (status==LiveStatus.CONNECTED) {
		                	app.setAuthClient(aClient);
		                	app.setSession(session);
		                	LiveConnectClient conn = new LiveConnectClient(session);
		                    app.setConnectClient(conn);
		                    activity.refreshAsync();
		                }else{
			            	context.sendToast(context.getString(R.string.msg_error_connect));
			                context.onProgressStatus(false);
		                }
		            }
		        });
			}			
		}catch(Exception e){
			Log.e(Constant.TAG, e.getMessage());
			context.onProgressStatus(false);
		}
	}
	
	public void syncFiles(LiveConnectClient mClient,String path){
		try {
			String parent = path;
			if(!Constant.SKYFRIVE_PATH_RECENT_DOCS.equals(path)){
				path += "/files";
			}
			LiveOperation operation = mClient.get(path);   
			JSONObject result = operation.getResult();
			List<SkyDriveObject> files = new ArrayList<SkyDriveObject>();
			boolean succ = !result.has(JsonKeys.ERROR);
			if(succ){
				JSONArray data = result.optJSONArray(JsonKeys.DATA);
				for (int i = 0; i < data.length(); i++) {
		            SkyDriveObject skyDriveObj = SkyDriveObject.create(data.optJSONObject(i));
		            files.add(skyDriveObj);
		        }
				
				if(Constant.SKYFRIVE_PATH_RECENT_DOCS.equals(parent)){
					updateRecentDocs(files,parent);
				}else if(Constant.SKYFRIVE_PATH_SHARED.equals(parent)){
					updateSharedDocs(files,parent);
				}else{
					update(files,parent);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}	
	
	public void openFile(FileListActivity context, SkyDriveObject item){
		String fileName = CUtil.buildFileName(item);
        final File file = new File(director+"/SkyDrive/"+fileName);
		String ext = CUtil.getFileExtesion(item.getName());
        if(file.exists()){
        	if (item.getType().equals(SkyDrivePhoto.TYPE)){						
        		Intent intent = new Intent(context,ImagePagerActivity.class);
				intent.putExtra(Constant.PARAM_ID, item.getId());
				intent.putExtra(Constant.PARAM_PATH, item.getParentId());
				context.startActivity(intent);
    		}else if("txt".equalsIgnoreCase(ext)){
    			Intent intent = new Intent(context,EditorActivity.class);
    			intent.putExtra(Constant.PARAM_ITEM_NAME, fileName);
    			intent.putExtra(Constant.PARAM_PATH, item.getParentId());
    			intent.putExtra(Constant.PARAM_ID, item.getId());
    			intent.putExtra(Constant.PARAM_OPERATION, EditorActivity.TEXT_FILE_EDIT);
    			context.startActivity(intent);
    		}else{
    			if(ext.length()==0){
    				context.showToast(context.getString(R.string.msg_error_open_file),true);
    			}else{
    				try{
                        ext = ext.toLowerCase();                        
                        
    					if(Constant.musicFileType.contains(ext.toLowerCase())){
    						Intent intent = new Intent(context,AudioPlayerActivity.class);
    						intent.putExtra(Constant.PARAM_PATH, file.getPath());
    						context.startActivity(intent);    						
    					}else{
    						Intent intent = new Intent();
                            intent.setAction(android.content.Intent.ACTION_VIEW);                   
                            MimeTypeMap mime = MimeTypeMap.getSingleton();
                            String type = mime.getMimeTypeFromExtension(ext);                  
                            intent.setDataAndType(Uri.fromFile(file),type);                   
                            context.startActivity(intent);
    					}
    				}catch(Exception e){
    					//TODO handle not supported file
    					Log.d(Constant.TAG, e.getMessage(), e);
    					context.showToast(context.getString(R.string.msg_error_no_app_open),true);
    				}
    			}
    		}
        }else{
    		context.showDialogOpen(item.getId(),item.getParentId(),item.toJson().toString());
        }
	}
	
	public boolean isDownloaded(SkyDriveObject item){
		boolean isDownloaded = false;
		if(new File(director+"/SkyDrive/"+CUtil.buildFileName(item)).exists()){
			isDownloaded = true;
		}
		return isDownloaded;
	}
	
	public boolean initUploadPhotos(LiveConnectClient client,String path){
		boolean hasNew = false;
		SharedPreferences sp = context.getSharedPreferences(Constant.FOLDER_LOG_CAMERA_FOLDER, 0);
		SharedPreferences spTemp = context.getSharedPreferences(Constant.FOLDER_LOG_CAMERA_FOLDER_TEMP, 0);		
		
		//TODO some devices have different camera path.
        File dcim = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM");
        List<File> photos = ImageFileViewer.getListFiles(dcim.getAbsolutePath());
        for(File photo : photos){
        	if(isNewPhoto(path,sp,photo,path)){
        		spTemp.edit().putString(photo.getAbsolutePath(), photo.getAbsolutePath()).commit();
        		hasNew = true;
        	}
        }
        spTemp.edit().commit();
        
        return hasNew;
        
	}
	
	private boolean isNewPhoto(String path,SharedPreferences sp,File photo,String uploadFolderId){
		boolean isNew = false;
		if(!sp.contains(photo.getAbsolutePath())){
			SkyDriveObject obj = this.getFileByName(photo.getName(),uploadFolderId);
			if(obj==null || !obj.getParentId().equals(path)){
				isNew = true;
			}
		}
		
		return isNew;
	}
	
	public boolean createCameraUploadFolder(LiveConnectClient mClient){
		boolean flag = false;
		JSONObject body = new JSONObject();
        try {
                body.put("name", Constant.CAMERA_UPLOAD_FOLDER);
                LiveOperation operation = mClient.post("me/skydrive", body);
                JSONObject result = operation.getResult();
                flag = !result.has(JsonKeys.ERROR);
				if(flag){
					SkyDriveObject folder = SkyDriveObject.create(result);
					folder.setParent(Constant.SKYFRIVE_PATH_HOME);
					addFile(folder);
				}
        } catch (Exception e) {
                Log.e(Constant.TAG, e.getMessage(),e);
        }
        
		return flag;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
